﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace HttpTest
{
    public class HttpClient
    {
        public enum RequestMethod
        {
            GET,
            POST,
            PUT,
            DELETE
        }
        private string _ip;
        public string Ip { get => _ip; set => _ip = value; }
        private int _port;
        public int Port { get => _port; set => _port = value; }

        public HttpClient(string ip, int port)
        {
            Ip = ip;
            Port = port;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="endpoint">like [/path/endpoint/]</param>
        /// <param name="requestBody"></param>
        /// <param name="requestMethod"></param>
        /// <returns></returns>
        public string request(string endpoint, string requestBody, RequestMethod requestMethod, string ContentType = "application/json")
        {
            try
            {
                string requestUrl = string.Format("http://{0}:{1}{2}", Ip, Port, endpoint);
                var request = (HttpWebRequest)WebRequest.Create(requestUrl);
                request.Timeout = 10000;
                request.ProtocolVersion = HttpVersion.Version11;
                request.ContentType = "application/json";
                request.Method = requestMethod.ToString();
                var requestStream = request.GetRequestStream();
                var data = Encoding.UTF8.GetBytes(requestBody);
                requestStream.Write(data, 0, data.Length);

                var response = request.GetResponse();

                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    string content = reader.ReadToEnd();
                    return content;
                }
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show("timeout:" + ex.Message);
                return "";
            }

        }

        public string Post(string endpoint, string requestBody)
        {
            return request(endpoint, requestBody, RequestMethod.POST);
        }

        public string Get(string endpoint, string requestBody)
        {
            return request(endpoint, requestBody, RequestMethod.GET);
        }

        public string Delete(string endpoint, string requestBody)
        {
            return request(endpoint, requestBody, RequestMethod.DELETE);
        }

        public string Put(string endpoint, string requestBody)
        {
            return request(endpoint, requestBody, RequestMethod.PUT);
        }


        public string UploadRequest(string endpoint, string filePath)
        {
            // 时间戳，用做boundary
            string timeStamp = DateTime.Now.Ticks.ToString("x");
            //根据uri创建HttpWebRequest对象
            HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(string.Format("http://{0}:{1}{2}", Ip, Port, endpoint));
            httpReq.Method = "POST";
            httpReq.AllowWriteStreamBuffering = false; //对发送的数据不使用缓存
            httpReq.Timeout = 300000;  //设置获得响应的超时时间（300秒）
            httpReq.ContentType = "multipart/form-data; boundary=" + timeStamp;

            //文件
            FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            BinaryReader binaryReader = new BinaryReader(fileStream);

            //头信息
            string boundary = "--" + timeStamp;
            string dataFormat = boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";filename=\"{1}\"\r\nContent-Type:application/octet-stream\r\n\r\n";
            string header = string.Format(dataFormat, "file", Path.GetFileName(filePath));
            byte[] postHeaderBytes = Encoding.UTF8.GetBytes(header);

            //结束边界
            byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + timeStamp + "--\r\n");

            long length = fileStream.Length + postHeaderBytes.Length + boundaryBytes.Length;

            httpReq.ContentLength = length;//请求内容长度

            try
            {
                //每次上传4k
                int bufferLength = 4096;
                byte[] buffer = new byte[bufferLength];

                //已上传的字节数
                long offset = 0;
                int size = binaryReader.Read(buffer, 0, bufferLength);
                Stream postStream = httpReq.GetRequestStream();

                //发送请求头部消息
                postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);

                while (size > 0)
                {
                    postStream.Write(buffer, 0, size);
                    offset += size;
                    size = binaryReader.Read(buffer, 0, bufferLength);
                }

                //添加尾部边界
                postStream.Write(boundaryBytes, 0, boundaryBytes.Length);
                postStream.Close();

                //获取服务器端的响应
                using (HttpWebResponse response = (HttpWebResponse)httpReq.GetResponse())
                {
                    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                    {
                        string content = reader.ReadToEnd();
                        return content;
                    }
                }
            }
            catch (Exception ex)
            {
                fileStream.Close();
                binaryReader.Close();
                System.Diagnostics.Debug.WriteLine("文件传输异常： " + ex.Message);
                return ex.Message;
            }
        }
    }
}
